package com.ysy.logistics.service.stock.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ysy.common.resp.ResultData;
import com.ysy.logistics.entities.echarts.PieTotal;
import com.ysy.logistics.entities.sale.CusOrder;
import com.ysy.logistics.entities.stock.InBoundList;
import com.ysy.logistics.entities.stock.StoreGoods;
import com.ysy.logistics.entities.stock.StoreHouse;
import com.ysy.logistics.entities.stock.dto.StoreGoodsDto;
import com.ysy.logistics.entities.supplier.SupOrder;
import com.ysy.logistics.entities.system.Dict;
import com.ysy.logistics.mapper.sale.CusOrderMapper;
import com.ysy.logistics.mapper.stock.InBoundListMapper;
import com.ysy.logistics.mapper.stock.StoreGoodsMapper;
import com.ysy.logistics.mapper.stock.StoreHouseMapper;
import com.ysy.logistics.mapper.supplier.SupOrderMapper;
import com.ysy.logistics.mapper.system.DictMapper;
import com.ysy.logistics.service.stock.StoreGoodsService;
import com.ysy.logistics.util.PageInfo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassDescription:
 * @Author:姚斯羽
 * @Create:2025/4/3 17:42
 **/
@Service
@Slf4j
public class StoreGoodsServiceImpl extends ServiceImpl<StoreGoodsMapper, StoreGoods> implements StoreGoodsService {

    @Resource
    private StoreGoodsMapper storeGoodsMapper;
    @Resource
    private StoreHouseMapper storeHouseMapper;
    @Resource
    private InBoundListMapper inBoundListMapper;
    @Autowired
    private SupOrderMapper supOrderMapper;
    @Resource
    private CusOrderMapper cusOrderMapper;
    @Resource
    private DictMapper dictMapper;

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ResultData inbound(List<StoreGoods> addStoreGoodsList, List<StoreGoods> updateStoreGoodsList, InBoundList inBoundList, Integer addStoreGoodsCapacity) {

        inBoundList.setInBoundStatus("0");
        inBoundList.setCreateTime(new Date());
        //构建入库单编号
        //供货商汉字首字母
        String firstLetter = PinyinUtil.getFirstLetter(inBoundList.getInBoundResponsible(), "").toUpperCase();
        //获取当前年月日小时分秒
        String date = DateUtil.format(new Date(), "yyyyMMddHHmmss");
        inBoundList.setInBoundNo(firstLetter + date);
        //读取仓库信息
        StoreHouse storeHouse = storeHouseMapper.selectById(inBoundList.getWarehouseId());
        if (Objects.isNull(storeHouse)) {
            return ResultData.fail("仓库不存在");
        }
        //判断仓库容量是否充足
        if (storeHouse.getCapacity() < addStoreGoodsCapacity + storeHouse.getUsedCapacity()) {
            return ResultData.fail("仓库容量不足,请更换入库仓库");
        }
        //保存商品信息
        this.saveBatch(addStoreGoodsList);
        //更新商品信息
        this.updateBatchById(updateStoreGoodsList);
        //添加入库信息
        inBoundListMapper.insert(inBoundList);
        //修改采购单状态
        LambdaUpdateWrapper<SupOrder> supOrderLqw = new LambdaUpdateWrapper<>();
        supOrderLqw.set(SupOrder::getStorageStatus, "1")
                .set(SupOrder::getStorageTime, new Date())
                .eq(SupOrder::getId, inBoundList.getInBoundTypeId());
        supOrderMapper.update(supOrderLqw);
        //更新仓库信息
        StoreHouse updateStoreHouse = new StoreHouse();
        updateStoreHouse.setId(storeHouse.getId());
        updateStoreHouse.setUsedCapacity(storeHouse.getUsedCapacity() + addStoreGoodsCapacity);
        storeHouseMapper.updateById(updateStoreHouse);
        return ResultData.success();
    }

    @Override
    public Page<StoreGoodsDto> listByPage(PageInfo<StoreGoodsDto> pageInfo) {
        StoreGoodsDto criteria = Optional.ofNullable(pageInfo.getCriteria()).orElse(new StoreGoodsDto());
        return storeGoodsMapper.listByPage(pageInfo.getPage(), criteria);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ResultData saveBackInBound(List<InBoundList> newInBoundList, List<StoreHouse> storeHouseList, List<StoreGoods> updateStoreGoodsList) {
        //保存入库单
        inBoundListMapper.insert(newInBoundList);
        //更新商品信息
        storeGoodsMapper.insertOrUpdate(updateStoreGoodsList);
        //更新仓库信息
        storeHouseMapper.insertOrUpdate(storeHouseList);
        //修改销售单信息
        String orderId = newInBoundList.get(0).getInBoundTypeId();
        LambdaUpdateWrapper<CusOrder> cusOrderLqw = new LambdaUpdateWrapper<>();
        cusOrderLqw.set(CusOrder::getStorageStatus, "2")
                .set(CusOrder::getOrderStatus, 4);
        cusOrderLqw.eq(CusOrder::getId, orderId);
        cusOrderMapper.update(cusOrderLqw);
        return ResultData.success();
    }

    @Override
    public List<PieTotal> goodsTypetotal() {
        //查询出商品类型
        LambdaQueryWrapper<Dict> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Dict::getName, "商品类型");
        List<Dict> dicts = dictMapper.selectList(lambdaQueryWrapper);
        List<PieTotal> pieTotalList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(dicts)) {
            Dict dict = dicts.get(0);
            //查询出商品类型
            lambdaQueryWrapper.clear();
            lambdaQueryWrapper.eq(Dict::getPid, dict.getId());
            List<Dict> typeList = dictMapper.selectList(lambdaQueryWrapper);
            if (CollectionUtil.isNotEmpty(typeList)) {
                //循环统计
                pieTotalList = typeList.stream()
                        .map(type -> {
                            PieTotal pieTotal = new PieTotal();
                            pieTotal.setName(type.getName());
                            //统计数量
                            Long total = storeGoodsMapper.totalGoodsNumByType(type.getNum());
                            total = total == null ? 0 : total;
                            pieTotal.setValue(total);
                            return pieTotal;
                        }).collect(Collectors.toList());
            }

        }
        return pieTotalList;
    }
}
